package cate.game.activity.customwarorder;

import cate.common.table.activity.customwarorder.row.CustomWarorderBaseRow;
import cate.common.table.activity.customwarorder.row.CustomWarorderChooseRow;
import cate.common.table.activity.customwarorder.row.CustomWarorderLevelRwdRow;
import cate.common.table.d.GDOperation;
import cate.common.table.d.GDWarOrder;
import cate.common.util.GameResult;
import cate.game.activity.base.core.SubActivitySingle;
import cate.game.activity.customwarorder.msg.CustomWarOrderLevelResp;
import cate.game.mail.po.MailBuilder;
import cate.game.res.MixRes;
import cate.game.res.MixResAdder;
import cate.game.res.MixResItem;
import cate.game.role.mail.Mail;
import com.fasterxml.jackson.annotation.JsonIgnore;
import easy.java.dev.note.NoteClass;
import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcResult;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

@NoteClass("战令等级数据")
public class RoleCustomWarOrderLevel extends SubActivitySingle<RoleCustomWarOrder> {

	@NoteField("激活类型")
	public byte activeType;

	@NoteField(value = "本期经验",detail = "有上限 超出的部分另外记录")
	public long exp;

	@NoteField(value = "超出的经验值",detail = "用于每天领取最后的宝箱 领完后会清除")
	public long overFlowExp;

	@NoteField(value = "基础奖励领取状态",detail = "记录的是等级")
	public Set<Integer> baseGot;

	@NoteField(value = "进阶奖励领取状态",detail = "记录的是等级")
	public Set<Integer> advanceGot;

	@Override
	public void initialize(RoleCustomWarOrder parent){
		super.initialize(parent);
		if (baseGot == null) {
			baseGot = new HashSet<>();
		}
		if (advanceGot == null) {
			advanceGot = new HashSet<>();
		}
	}

	public void excelCheck() {

	}

	public void beforeOver(List<Integer> chooseItems) {
		handleResult(chooseItems);
	}

	public void clear() {
		activeType = GDWarOrder.ActiveType.NONE;
		exp = 0;
		overFlowExp = 0;
		baseGot.clear();
		advanceGot.clear();
	}

	public int configGroup() {
		CustomWarorderBaseRow baseRow = parent.getRow();
		if (baseRow != null) {
			return baseRow.levelGroup;
		} else {
			return -1;
		}
	}

	public boolean allowPay(byte payItemType) {
		switch (payItemType) {
			case GDWarOrder.PayItemType.BASE:
			case GDWarOrder.PayItemType.ADVANCE:
				return !activeAdvance();
			case GDWarOrder.PayItemType.UPGRADE:
				return activeType == GDWarOrder.ActiveType.BASE;
			default:
				return false;
		}
	}

	public void onPaySuccess(byte payItemType) {
		switch (payItemType) {
			case GDWarOrder.PayItemType.BASE:
				this.activeType = GDWarOrder.ActiveType.BASE;
				return;
			case GDWarOrder.PayItemType.ADVANCE:
			case GDWarOrder.PayItemType.UPGRADE:
				this.activeType = GDWarOrder.ActiveType.ADVANCE;
				return;
			default:
		}
	}

	/**
	 * 进阶战令是否解锁
	 */
	public boolean activeAdvance() {
		return activeType != GDWarOrder.ActiveType.NONE;
	}


	/**
	 * 购买经验
	 */
	public GameResult<Void> buyExp(int num) {
		GameResult<Void> r = new GameResult<>();
		CustomWarorderBaseRow row = parent.getRow();
		if (row == null) {
			return r.fail("配置不存在");
		}
		if (num <= 0) {
			return r.fail("购买数量有误");
		}

		MixRes consume = new MixRes(row.buyExpCostStr).multiply(num);
		GameResult<MixResItem> consumeRes = consume.consume(parent.getRole());
		if (!consumeRes.ok()) {
			return r.fail(consumeRes);
		}
		addExp(row.buyExp * num);
		noticeUpdate();
		return r.success();
	}



	/** 获取最大经验值
	 */
	@JsonIgnore
	private int getMaxExp(){
		return role.getGame().table.customWarorder.level.getMaxExp(configGroup());
	}


	/** 领取等级奖励 */
	public GameResult<Void> getLevelReward(int level, List<Integer> chooseItems) {
		GameResult<Void> r = new GameResult<>();
		CustomWarorderLevelRwdRow rwdRow = role.getGame().table.customWarorder.level.getRowByLevel(configGroup(), level);
		if (rwdRow == null) {
			return r.fail("奖励不存在");
		}
		if (exp < rwdRow.totalExp) {
			return r.fail("等级不足");
		}
		MixRes reward = new MixRes();
		if (!baseGot.contains(level)) {
			baseGot.add(level);
			reward.addList(new MixRes(rwdRow.baseRwdStr));
		}
		if (activeAdvance() && !advanceGot.contains(level)) {
			advanceGot.add(level);
			reward.addList(new MixRes(rwdRow.advanceRwdStr));
			reward.addList(addChooseReward(rwdRow, chooseItems));
		}
		if (reward.isEmpty()) {
			return r.fail("没有可领取的奖励");
		}
		new MixResAdder().setRes(reward).
				setOperation(GDOperation.A_WAR_ORDER).
				setOperationSub(level).
				setDialogReward(true).exe(role);
		noticeUpdate();
		return r.success();
	}


	/** 发送未领取的奖励 */
	private void handleResult(List<Integer> chooseItems) {
		CustomWarorderBaseRow row = parent.getRow();
		if (row == null) {
			return;
		}
		if (!activeAdvance()) {
			return;
		}
		MixRes reward = new MixRes();
		for (CustomWarorderLevelRwdRow rewardRow : parent.getRole().getGame().table.customWarorder.level.getRowsByGroup(configGroup())) {
			if (exp < rewardRow.totalExp) {
				continue;
			}
			if (advanceGot.contains(rewardRow.level)) {
				continue;
			}
			reward.addList(new MixRes(rewardRow.advanceRwdStr));
			reward.addList(addChooseReward(rewardRow, chooseItems));
		}
		if (reward.isEmpty() || row.mailId <= 0) {
			return;
		}
		Mail mail = new MailBuilder()
				.setContentId(row.mailId)
				.setReward(reward)
				.setOperation(GDOperation.A_WAR_ORDER)
				.build();
		parent.getRole().getMail().add(mail);
	}

	private MixRes addChooseReward(CustomWarorderLevelRwdRow rewardRow, List<Integer> chooseItems) {
		MixRes reward = new MixRes();
		if (rewardRow.hasCustomRwd) {
			for (Integer chooseId : chooseItems) {
				CustomWarorderChooseRow chooseRow = role.getGame().table.customWarorder.choose.get(chooseId);
				if (chooseRow != null) {
					reward.addList(new MixRes(chooseRow.baseRewardStr).multiply(rewardRow.scale));
				}
			}
		}
		return reward;
	}

	/**
	 * 一键领取
	 */
	public GameResult<Void> batchGot(List<Integer> chooseItems) {
		GameResult<Void> r = new GameResult<>();
		MixRes reward = new MixRes();
		for (CustomWarorderLevelRwdRow rewardRow : parent.getRole().getGame().table.customWarorder.level.getRowsByGroup(configGroup())) {
			if (exp < rewardRow.totalExp) {
				continue;
			}
			if (!baseGot.contains(rewardRow.level)) {
				reward.addList(new MixRes(rewardRow.baseRwdStr));
				baseGot.add(rewardRow.level);
			}
			if (activeAdvance()) {
				if (!advanceGot.contains(rewardRow.level)) {
					reward.addList(new MixRes(rewardRow.advanceRwdStr));
					advanceGot.add(rewardRow.level);
					reward.addList(addChooseReward(rewardRow, chooseItems));
				}
			}
		}
		if (activeAdvance()) {
			reward.addList(calBoxRwd());
		}
		if (reward.isEmpty()) {
			return r.fail("没有可领取的奖励");
		}
		new MixResAdder().setRes(reward).setOperation(GDOperation.A_WAR_ORDER).setDialogReward(true).exe(role);
		noticeUpdate();
		return r;
	}

	/**
	 * 领取宝箱奖励
	 * @return
	 */
	@JsonIgnore
	public GameResult<Void> getBoxRwd() {
		GameResult<Void> r = new GameResult<>();
		if (!activeAdvance()) {
			return r.fail("激活战令后可领取");
		}
		if (overFlowExp < parent.getRow().exBoxExpRequierd || parent.getRow().exBoxExpRequierd <= 0) {
			return r.fail("未达到领取条件");
		}
		MixRes reward = calBoxRwd();
		new MixResAdder().setRes(reward).setOperation(GDOperation.A_WAR_ORDER).setDialogReward(true).exe(role);
		noticeUpdate();
		return r.success();
	}

	private MixRes calBoxRwd() {
		MixRes reward = new MixRes();
		int exBoxExpRequierd = parent.getRow().exBoxExpRequierd;
		if (exBoxExpRequierd <= 0) {
			return reward;
		}
		int boxNum = (int) (overFlowExp / exBoxExpRequierd);
		if (boxNum > 0) {
			overFlowExp -= exBoxExpRequierd * boxNum;
			reward.addList(new MixRes(parent.getRow().exBoxRwdStr).multiply(boxNum));
		}
		return reward;
	}

	@Override
	public void onDaySpan(boolean silence) {

	}

	public EcResult<Void> addExpByItem(int itemId, long num) {
		EcResult<Void> r = new EcResult();
		if (itemId == parent.getRow().expItemId) {
			addExp(num);
			noticeUpdate();
			return r.success();
		}
		return r.fail();
	}

	public void addExp(long add) {
		if (add <= 0) {
			return;
		}
		this.exp += add;
		int expMax = getMaxExp();
		if (exp > expMax) {
			this.overFlowExp += (exp - expMax);
			this.exp = expMax;
		}
	}


	public void noticeUpdate() {
		parent.getRole().sendNow(new CustomWarOrderLevelResp(funcId(),this));
	}


	public void onMergeSettle(List<Integer> chooseItems) {
		if (!activeAdvance()) {
			return;
		}
		MixRes reward = new MixRes();
		for (CustomWarorderLevelRwdRow rewardRow : parent.getRole().getGame().table.customWarorder.level.getRowsByGroup(configGroup())) {
			if (!advanceGot.contains(rewardRow.level)) {
				reward.addList(new MixRes(rewardRow.advanceRwdStr));
				advanceGot.add(rewardRow.level);
				reward.addList(addChooseReward(rewardRow, chooseItems));
			}
		}
		if (reward.isEmpty()) {
			return;
		}
		Mail mail = new MailBuilder().setContentId(parent.getRow().mailId).setReward(reward).setOperation(GDOperation.A_WAR_ORDER).build();
		role.getMail().add(mail);
	}
}
